package lp2.projeto.agenda;


import java.awt.*;
import java.awt.event.*;

import java.io.IOException;
import java.util.ArrayList;

import javax.swing.*;



import lp2.projeto.gerenciador.*;
import lp2.projeto.horario.Horario;
import lp2.projeto.horario.Mes;
import lp2.projeto.database.*;


public class AgendaGrafica extends JFrame {
	private static final long serialVersionUID = 1790196675247639019L;
	protected static Gerenciador gerente; 
	protected static Color backgroundColor;
	protected static avisoJDialog avisoJDialog;
	
	private static Perfil perfil;

	
// Referencias aos items do Menu
	// Menu Principal
	protected static JMenuBar menuBar;
	protected static JMenuItem modificarPerfilItem ;
	protected static JMenuItem salvarItem;
	protected static JMenuItem sairItem;
	// Menu Contatos
	protected static JMenuItem adicionarContatoItem;
	protected static JMenuItem removerContatoItem;
	protected static JMenuItem modificarContatoItem;
	protected static JMenuItem buscarContatoItem;
	// Menu Eventos
	protected static JMenuItem adicionarEventoItem;
	protected static JMenuItem removerEventoItem;
	protected static JMenuItem modificarEventoItem;
	protected static JMenuItem buscarEventoItem;
	
	// Menu Ajuda
	protected static JMenu ajudaMenu;
	protected static JMenuItem sobreAjudaItem;
	
// Referencias ao JPanePrincipal
	//Botoes de Acao
	protected static JButton atualizaListas;
	protected static JButton listarEventosDoContato;
	protected static JButton listarContatosDoEvento;
	protected static JButton adicionarContatoAEvento ;
	protected static JButton removerContatoDeEvento;
	protected static JButton exibirCalendario; 
	// Botoes de Contato
	protected static JButton novoContato;
	protected static JButton modificarContato ;
	protected static JButton visualizarContato;
	protected static JButton removerContato;
	// Botoes de Evento
	protected static JButton novoEvento;
	protected static JButton modificarEvento ;
	protected static JButton visualizarEvento;
	protected static JButton removerEvento;
	// JList's e ScrollPane's
	protected static JList listaContatosJList;
	protected static JList listaEventosJList;
	protected static DefaultListModel listaContatosListModel;
	protected static DefaultListModel listaEventosListModel;
	private static ListaContatos listaContatos;
	private static ListaEventos listaEventos;
	
	public AgendaGrafica(){	
		super("Agenda Multitudo");
		this.setJMenuBar(setJMenuBar());
		add(getJPanePrincipal());
		
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				sair();
			}
		});
		
		this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		this.setSize(new Dimension(600,600));
		this.setVisible(true);

	}
	public static void main(String[] args)  {
		try {
			gerente =  (Gerenciador) Database.lerObjeto("DatabaseGerente");
		} catch (IOException e) {
		}
		if (gerente == null) gerente = new Gerenciador();
		
		try {
			perfil = (Perfil) Database.lerObjeto("DatabasePerfil");
		} catch (IOException e) {
		}
		if (perfil == null) {
			perfil = new Perfil("", "", "");
			new PerfilJDialog(perfil);
		}

		@SuppressWarnings("unused")
		AgendaGrafica agendaMultitudo = new AgendaGrafica();
	}
	
	private JPanel getJPanePrincipal() {
		GridBagConstraints constraints = new GridBagConstraints();
		JPanel panel = new JPanel(new GridBagLayout());
		JPanel paneLabels;
		Font fonteBotoes = new Font("Courrier",Font.PLAIN,11); // Fonte dos botoes do JPanePrincipal
		backgroundColor = Color.GRAY; // Cor do background do JPanePrincipal
		panel.setBackground(backgroundColor);
		
	// Adicao do Label da lista de Contatos
		JLabel listaContatosLabel = new JLabel("Lista de Contatos");
		constraints.fill = GridBagConstraints.HORIZONTAL;  
		constraints.anchor = GridBagConstraints.CENTER; 
		constraints.weighty = 0; 
		constraints.weightx = 0.5;
		constraints.ipady = 15;  
		constraints.insets = new Insets(5,5,5,5); 
		constraints.gridx = 0;      
		constraints.gridwidth = 2;   
		constraints.gridy = 0;
		paneLabels = new JPanel(new FlowLayout(FlowLayout.CENTER));
		paneLabels.add(listaContatosLabel);
		paneLabels.setBackground(backgroundColor);
		panel.add(paneLabels,constraints);
		
	// Adicao do Label da Panel de Botoes
		JLabel botoesLabel = new JLabel("Acoes");
		constraints.fill = GridBagConstraints.HORIZONTAL;    
		constraints.anchor = GridBagConstraints.CENTER;
		constraints.weighty = 0; 
		constraints.weightx = 0.2;
		constraints.ipady = 15;  
		constraints.insets = new Insets(5,5,5,5); 
		constraints.gridx = 2;      
		constraints.gridwidth = 1;   
		constraints.gridy = 0;
		paneLabels = new JPanel(new FlowLayout(FlowLayout.CENTER));
		paneLabels.add(botoesLabel);
		paneLabels.setBackground(backgroundColor);
		panel.add(paneLabels,constraints);
		
	// Adicao do Label da lista de Eventos
		JLabel listaEventosLabel = new JLabel("Lista de Eventos");
		constraints.fill = GridBagConstraints.HORIZONTAL;    
		constraints.anchor = GridBagConstraints.CENTER;
		constraints.weighty = 0; 
		constraints.weightx = 0.5;
		constraints.ipady = 15;  
		constraints.insets = new Insets(5,5,5,5); 
		constraints.gridx = 3;      
		constraints.gridwidth = 2;   
		constraints.gridy = 0;
		paneLabels = new JPanel(new FlowLayout(FlowLayout.CENTER));
		paneLabels.add(listaEventosLabel);
		paneLabels.setBackground(backgroundColor);
		panel.add(paneLabels,constraints);
		
	// Adicao da lista de contatos
		listaContatos = new ListaContatos(gerente.getContatos(), "Todos os contatos");
		constraints.fill = GridBagConstraints.BOTH;
		constraints.ipady = 0;     
		constraints.weighty = 1; 
		constraints.weightx = 0.5;
		constraints.insets = new Insets(5,5,5,5); 
		constraints.gridx = 0;      
		constraints.gridwidth = 2;
		constraints.gridheight = 3;
		constraints.gridy = 1;       
		panel.add(listaContatos,constraints);
		
	// Adicao da lista de eventos
		listaEventos = new ListaEventos(gerente.getEventos(), "Todos os eventos");
		constraints.fill = GridBagConstraints.BOTH;
		constraints.ipady = 0;     
		constraints.weighty = 1; 
		constraints.weightx = 0.5;
		constraints.insets = new Insets(5,5,5,5); 
		constraints.gridx = 3;      
		constraints.gridwidth = 2; 
		constraints.gridheight = 3;
		constraints.gridy = 1; 
		panel.add(listaEventos,constraints);
		
		
	// Panel contendo os botoes de acoes que ficam entre as listas
		JPanel paneBotoes = new JPanel(new GridLayout(0,1,0,20));
		paneBotoes.setBackground(backgroundColor);
		
	// Botao para adicao de contato a evento
		adicionarContatoAEvento = new JButton("Adicionar Contato a Evento");
		adicionarContatoAEvento.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				Contato contato = listaContatos.getContatoSelecionado();
				Evento evento = listaEventos.getEventoSelecionado();
				String mensagem;
				
				if (contato == null || evento == null) {
					mensagem = "Por favor selecione um contato e um evento";
				} else if (gerente.adicionaContatoAEvento(contato, evento)) {
					mensagem = "O contato foi adicionado ao evento";
				} else {
					mensagem = "O contato jah pertencia ao evento";
				}
				
				avisoJDialog = new avisoJDialog(mensagem);
				avisoJDialog.setVisible(true);	
				
				atualizarListas();
			}
		});
		adicionarContatoAEvento.setFont(fonteBotoes);
		paneBotoes.add(adicionarContatoAEvento);
		
		removerContatoDeEvento = new JButton("Remover Contato de Evento");
		removerContatoDeEvento.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				Contato contato = listaContatos.getContatoSelecionado();
				Evento evento = listaEventos.getEventoSelecionado();
				String mensagem;
				
				if (contato == null || evento == null) {
					mensagem = "Por favor selecione um contato e um evento";
				} else if (!gerente.getContatoPorEvento(evento).contains(contato)) {
					mensagem = "O contato nao pertence ao evento";
				} else {
					gerente.removeContatoDeEvento(contato, evento);
					mensagem = "O contato foi removido do evento";
				}
				
				avisoJDialog = new avisoJDialog(mensagem);
				avisoJDialog.setVisible(true);
				
				atualizarListas();
			}			
		});
		removerContatoDeEvento.setFont(fonteBotoes);
		paneBotoes.add(removerContatoDeEvento);
		
	// Botao para listagem de Contatos do Evento
		listarContatosDoEvento = new JButton("Listar Contatos do Evento");
		listarContatosDoEvento.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				Evento evento = listaEventos.getEventoSelecionado();
				if (evento == null) { 
					avisoJDialog = new avisoJDialog("Por favor selecione um Evento da Lista");
					avisoJDialog.setVisible(true);
				} else {
					listaContatos.setContatos(gerente.getContatoPorEvento(evento), "Contatos do evento " + evento.getNome());
				}
			}
		});
		listarContatosDoEvento.setFont(fonteBotoes);
		paneBotoes.add(listarContatosDoEvento);
		
	// Botao para listagem de Eventos do Contato
		listarEventosDoContato = new JButton("Listar Eventos do Contato");
		listarEventosDoContato.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				Contato contato = listaContatos.getContatoSelecionado();
				if (contato == null) {
					avisoJDialog = new avisoJDialog("Por favor selecione um Contato da Lista");
					avisoJDialog.setVisible(true);					
				} else {
					listaEventos.setEventos(gerente.getEventoPorContato(contato), "Eventos do contato " + contato.getNome());
				}
			}
		});
		listarEventosDoContato.setFont(fonteBotoes);
		paneBotoes.add(listarEventosDoContato);
		
	// Botao para atualizacao das Listas
		atualizaListas = new JButton("Atualizar Listas");
		atualizaListas.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				atualizarListas();	
			}
		});
		atualizaListas.setFont(fonteBotoes);
		paneBotoes.add(atualizaListas);
	// Botao para exibicao do calendario
		exibirCalendario = new JButton("Exibir Calendario de Eventos");
		exibirCalendario.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				JDialog calendarioJDialog = new CalendarioJDialog();
				calendarioJDialog.setVisible(true);
				
			}
		});
		exibirCalendario.setFont(fonteBotoes);
		paneBotoes.add(exibirCalendario);
		
	// Adicao do panel contendo os botoes de acoes
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.NORTH;
		constraints.ipadx = 0;     
		constraints.weighty = 0; 
		constraints.weightx = 0;
		constraints.insets = new Insets(5,5,5,5); 
		constraints.gridx = 2;      
		constraints.gridwidth = 1; 
		constraints.gridheight = 3;
		constraints.gridy = 1; 
		panel.add(paneBotoes,constraints);
		
		
	// Panel contendo os botoes especificos de Contato
		JPanel panelContatos = new JPanel(new GridLayout(2,2,5,5));
		panelContatos.setBackground(backgroundColor);
		
	// Botao para adicao de um novo Contato a Lista
		novoContato = new JButton("Novo");
		novoContato.setFont(fonteBotoes);	
		novoContato.addActionListener(new ActionListener() {
		
			@Override
			public void actionPerformed(ActionEvent arg0) {
				CadastroContatoJDialog cadastroContatoJDialog = new CadastroContatoJDialog(null);
				cadastroContatoJDialog.setResizable(false);
				cadastroContatoJDialog.setVisible(true);
			}
		});
		
		panelContatos.add(novoContato);
				
	// Botao modificar um Contato da Lista
		modificarContato = new JButton("Modificar");
		modificarContato.setFont(fonteBotoes);
		modificarContato.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (listaContatos.getContatoSelecionado() != null ){
					CadastroContatoJDialog cadastroContatoJDialog = new CadastroContatoJDialog(
							listaContatos.getContatoSelecionado());
					cadastroContatoJDialog.setResizable(false);
					cadastroContatoJDialog.atualizaDados();
					cadastroContatoJDialog.setVisible(true);
				} else {
					avisoJDialog = new avisoJDialog("Por favor selecione um Contato da Lista");
					avisoJDialog.setVisible(true);
				}
				
				
			}
		});
		panelContatos.add(modificarContato);
				
	// Botao visualizar com detalhes um Contato da lista
		visualizarContato  = new JButton("Visualizar");	 
		visualizarContato.setFont(fonteBotoes);
		visualizarContato.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				if (listaContatos.getContatoSelecionado() != null ){
					CadastroContatoJDialog cadastroContatoJDialog = new CadastroContatoJDialog(
							listaContatos.getContatoSelecionado());
					cadastroContatoJDialog.setResizable(false);
					cadastroContatoJDialog.atualizaDados();
					cadastroContatoJDialog.trancaDados();
					cadastroContatoJDialog.setVisible(true);
				} else {
					avisoJDialog = new avisoJDialog("Por favor selecione um Contato da Lista");
					avisoJDialog.setVisible(true);
				}
				
			}
		});
		panelContatos.add(visualizarContato);
				
	// Botao para remover um Contato da Lista
		removerContato = new JButton("Remover");
		removerContato.setFont(fonteBotoes);
		removerContato.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				Contato contato = listaContatos.getContatoSelecionado();
				
				if (contato != null){
					listaContatos.removeContatoSelecionado();
					gerente.removeContato(contato);
				} else {
					avisoJDialog = new avisoJDialog("Por favor selecione um Contato da Lista");
					avisoJDialog.setVisible(true);
				}
				
			}
		});
		panelContatos.add(removerContato);
		
		
	// Adicao do panel contendo os botoes de acoes
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.CENTER;
		constraints.ipadx = 0;     
		constraints.weighty = 0; 
		constraints.weightx = 0;
		constraints.insets = new Insets(5,5,5,5); 
		constraints.gridx = 0;      
		constraints.gridwidth = 2; 
		constraints.gridheight = 1;
		constraints.gridy = 4; 
		panel.add(panelContatos,constraints);
		
	// Panel contendo os botoes especificos de Contato
		JPanel panelEventos = new JPanel(new GridLayout(2,2,5,5));
		panelEventos.setBackground(backgroundColor);
		
	// Botao para adicao de um novo Contato a Lista
		novoEvento = new JButton("Novo");
		novoEvento.setFont(fonteBotoes);
		novoEvento.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				java.awt.EventQueue.invokeLater(new Runnable() {
		            public void run() {
		            	VisualizadorDeEvento visu = new VisualizadorDeEvento(AgendaGrafica.this, true, null, false);
		            	visu.setVisible(true);
		            }
		        });
			}
		});
		panelEventos.add(novoEvento);
					
	// Botao modificar um Evento da Lista
		modificarEvento = new JButton("Modificar");
		modificarEvento.setFont(fonteBotoes);
		modificarEvento.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				java.awt.EventQueue.invokeLater(new Runnable() {
		            public void run() {
		                VisualizadorDeEvento dialog = new VisualizadorDeEvento(AgendaGrafica.this, true, listaEventos.getEventoSelecionado(), false);
		                dialog.setVisible(true);
		            }
		        });
			}
		});
		panelEventos.add(modificarEvento);
					
	// Botao visualizar com detalhes um Evento da lista
		visualizarEvento  = new JButton("Visualizar");	 
		visualizarEvento.setFont(fonteBotoes);
		visualizarEvento.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				java.awt.EventQueue.invokeLater(new Runnable() {
		            public void run() {
		                VisualizadorDeEvento dialog = new VisualizadorDeEvento(new javax.swing.JFrame(), true, listaEventos.getEventoSelecionado(), true);
		                dialog.setVisible(true);
		            }
		        });
			}
		});
		panelEventos.add(visualizarEvento);
				
	// Botao para remover um Evento da Lista
		removerEvento = new JButton("Remover");
		removerEvento.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				Evento evento = listaEventos.getEventoSelecionado();
				if (evento == null) {
					avisoJDialog = new avisoJDialog("Por favor selecione um Evento da Lista");
					avisoJDialog.setVisible(true);
				} else {
					listaEventos.removeEventoSelecionado();
					gerente.removeEvento(evento);
				}
			}
		});
		
		removerEvento.setFont(fonteBotoes);
		panelEventos.add(removerEvento );
		
	// Adicao do panel contendo os botoes de acoes
		constraints.fill = GridBagConstraints.NONE;
		constraints.anchor = GridBagConstraints.CENTER;
		constraints.ipadx = 0;     
		constraints.weighty = 0; 
		constraints.weightx = 0;
		constraints.insets = new Insets(5,5,5,5); 
		constraints.gridx = 3;      
		constraints.gridwidth = 2; 
		constraints.gridheight = 1;
		constraints.gridy = 4; 
		panel.add(panelEventos,constraints);
		
		
		return panel;
	}
	
	public static void atualizarListas() {
		listaContatos.setContatos(gerente.getContatos(), "Todos os contatos");
		listaEventos.setEventos(gerente.getEventos(), "Todos os eventos");
	}
	
	private void salvarPerfil() {
		try {
			Database.salvarObjeto("DatabaseGerente", gerente);
			Database.salvarObjeto("DatabasePerfil", perfil);
		} catch (Exception e) {
			avisoJDialog = new avisoJDialog("Erro no salvamento");
			avisoJDialog.setVisible(true);
		}
	}
	
	private void sair() {
		ActionListener acaoSim = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				salvarPerfil();
				System.exit(0);
			}
		}, acaoNao = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		};
		
		new DuasOpcoesJDialog("Sair", "Antes de sair, deseja salvar o perfil?", "Sim", acaoSim, "Nao", acaoNao);
	}
	
	private void listaEventosDaData(int dia, Mes mes, int ano) {
		ArrayList<Evento> eventos = new ArrayList<Evento>();
		
		for (Evento evento : gerente.getEventos())
			if (evento.iniciaNoDia(dia, mes, ano))
				eventos.add(evento);
		
		listaEventos.setEventos(eventos, "eventos em " + dia + "/" + mes.getNumero() + "/" + ano);
	}
	
	private JMenuBar setJMenuBar(){
		menuBar = new JMenuBar();
		menuBar.setBackground(Color.LIGHT_GRAY);
		menuBar.setBorderPainted(false);
		
		// Menu Principal ------------------------
		JMenu arquivoMenu = new JMenu("Arquivo");
		
		modificarPerfilItem = new JMenuItem("Modificar Perfil");
		modificarPerfilItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				new PerfilJDialog(perfil);
			}
		});
		
		salvarItem = new JMenuItem("Salvar Perfil");
		salvarItem.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				salvarPerfil();
			}
		});
		sairItem = new JMenuItem("Sair");
		sairItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				sair();
			}
		});
		
		arquivoMenu.add(modificarPerfilItem);
		arquivoMenu.add(salvarItem);
		arquivoMenu.addSeparator();
		arquivoMenu.add(sairItem);
		
		menuBar.add(arquivoMenu);
		
		// Menu dos Contatos ------------------------
		JMenu contatosMenu = new JMenu("Contatos");
		
		adicionarContatoItem = new JMenuItem("Adicionar");
		adicionarContatoItem.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				novoContato.doClick();
			}
		});
		removerContatoItem = new JMenuItem("Remover");
		removerContatoItem.addActionListener(new ActionListener() {
		
			@Override
			public void actionPerformed(ActionEvent e) {
				removerContato.doClick();	
			}
		});
		modificarContatoItem = new JMenuItem("Modificar");
		modificarContatoItem.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				modificarContato.doClick();
			}
		});		
		contatosMenu.add(adicionarContatoItem);
		contatosMenu.add(removerContatoItem);
		contatosMenu.add(modificarContatoItem);
		
		menuBar.add(contatosMenu);
		
		// Menu dos Eventos ------------------------
		JMenu eventosMenu = new JMenu("Eventos");
		
		adicionarEventoItem = new JMenuItem("Adicionar");
		adicionarEventoItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				novoEvento.doClick();
			}			
		});
		
		removerEventoItem = new JMenuItem("Remover");
		removerEventoItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				removerEvento.doClick();
			}			
		});
		
		modificarEventoItem = new JMenuItem("Modificar");
		modificarEventoItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				modificarEvento.doClick();
			}			
		});
		
		buscarEventoItem = new JMenuItem("Buscar evento pela data");
		buscarEventoItem.addActionListener(new ActionListener() {
			DataJDialog dialog;
			
			@Override
			public void actionPerformed(ActionEvent e) {
				ActionListener acaoOk = new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent e) {
						int dia = dialog.getDia();
						Mes mes = dialog.getMes();
						int ano = dialog.getAno();
						
						listaEventosDaData(dia, mes, ano);
					}
				};
				
				dialog = new DataJDialog("Informe a data dos eventos desejados", acaoOk);
				dialog.setVisible(true);
			}
		});
				
		eventosMenu.add(adicionarEventoItem);
		eventosMenu.add(removerEventoItem);
		eventosMenu.add(modificarEventoItem);
		eventosMenu.add(buscarEventoItem);
		
		menuBar.add(eventosMenu);
		
		// Menu de Ajuda
		ajudaMenu = new JMenu("Ajuda");
		
		sobreAjudaItem = new JMenuItem("Sobre");
		sobreAjudaItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				SobreJDialog dialog = new SobreJDialog();
				dialog.setVisible(true);
			}
		});
		
		ajudaMenu.add(sobreAjudaItem);
		menuBar.add(ajudaMenu);
		 
		
		return menuBar;
		
	}
}
